package com.yzl.meeting.framework.beans.factory.xml;

import com.yzl.meeting.framework.beans.exception.BeanDefinitionException;
import com.yzl.meeting.framework.beans.support.BeanDefinitionRegistry;
import com.yzl.meeting.framework.core.io.Resource;
import com.yzl.meeting.framework.pojo.BeanDefinition;
import com.yzl.meeting.framework.pojo.PropertyValue;
import com.yzl.meeting.framework.pojo.RuntimeBeanReference;
import com.yzl.meeting.framework.pojo.TypeStringValue;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.util.Iterator;

/**
 * @Title: XmlBeanDefinigionReader
 * @Author: 姚志立
 * @Description:装配xml中的bean对象
 * @Date: 2020/10/20 15:04
 * @Version: 1.0
 */
public class XmlBeanDefinitionReader {
    BeanDefinitionRegistry factory;

    public XmlBeanDefinitionReader(BeanDefinitionRegistry factory) {
        this.factory = factory;
    }


    public  void loadConfigurationFile(Resource fileName) {
        SAXReader saxReader = new SAXReader();
        try {
            Document document = saxReader.read(fileName.getInputStream());
            Element rootElement = document.getRootElement();
            Iterator<Element> beanIte = rootElement.elementIterator("bean");
            while (beanIte.hasNext()) {
                Element beanEle = beanIte.next();
                String beanId = beanEle.attributeValue("id");
                String beanClassName = beanEle.attributeValue("class");
                BeanDefinition beanDefinition = new BeanDefinition();
                beanDefinition.setTypeClass(Class.forName(beanClassName));
                beanDefinition.setTypeName(Class.forName(beanClassName).getName());
                String scope = beanEle.attributeValue("scope");
                if(scope == null){
                    scope = "";
                }
                beanDefinition.setScope(scope);
                //解析property标签
                parsePropertyEle(beanEle, beanDefinition);
                factory.registerBeanDefinition(beanId, beanDefinition);
            }
        } catch (Exception e) {
            throw new BeanDefinitionException("解析xml时，出现意外", e);
        }
    }


    private void parsePropertyEle(Element beanEle, BeanDefinition beanDefinition) {
        Iterator<Element> propertyIte = beanEle.elementIterator("property");
        while(propertyIte.hasNext()){
            Element propertyEle = propertyIte.next();
            PropertyValue pv = parsePropertyValue(propertyEle);
            beanDefinition.getPropertyValueList().add(pv);
        }
    }

    private PropertyValue parsePropertyValue(Element propertyEle) {
        boolean hasRefAttr = propertyEle.attributeValue("ref")!=null;
        boolean hasValueAttr = propertyEle.attributeValue("value")!=null;

        PropertyValue pv = new PropertyValue();
        pv.setPname(propertyEle.attributeValue("name"));
        if(hasRefAttr){
            RuntimeBeanReference rbr = new RuntimeBeanReference(propertyEle.attributeValue("ref"));
            pv.setValue(rbr);
        }else if(hasValueAttr){
            TypeStringValue tsv = new TypeStringValue(propertyEle.attributeValue("value"));
            pv.setValue(tsv);
        }
        return pv;
    }
}
